home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 076-100 / disk_097 / cutandpaste / getopt.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  4KB  |  165 lines

  1. /*
  2.  * getopt(), a verson of getopt for those who do not have it and do not
  3.  * want to steal the source from those that do.
  4.  *
  5.  * Same as getopt(3).
  6.  *    Returns the next option letter in argv that matches a letter in optstr.
  7.  *    Options are no longer parsed if the special option '--' is found
  8.  *    or an argument that does not start in '-'.
  9.  *    The global optind is set to the next index in argv to be processed.
  10.  *    The global optarg is set to the argument, if the option has one.
  11.  *    The global opterr can be set true if error messages are to be printed
  12.  *    on the standard error file, or false if no message to be printed.
  13.  *
  14.  * ARGUMENTS:
  15.  *    argc, argv - the argument count, and argument list
  16.  *    optstr     - the list of valid options. The character ":" following
  17.  *             an option letter indicates that this option must have an 
  18.  *             argument. For example "abc:". This implies that the -:
  19.  *             is not  a valid option.
  20.  *
  21.  * RETURNS:
  22.  *    Returns the next option letter, or EOF when all done. If an error
  23.  *    encountered then the character '?' is returned.
  24.  *
  25.  * John Weald
  26.  */
  27. #include <stdio.h>
  28.  
  29. /*
  30.  * Index into error array.
  31.  */
  32. #define BAD_OPT 0    /* option letter not in optstr            */
  33. #define MIS_ARG 1    /* option must have an argument            */
  34.  
  35. char *optarg;
  36. int optind = 1;        /* argv[0] is program name            */
  37. int opterr = 1;        /* If true print error message            */
  38.  
  39. /*
  40.  *
  41.  * The basic data structures are optind, and the pointer "p."
  42.  * optind keeps track of the next index into argv to parse arguments.
  43.  * p is used to walk along the argv items looking for option letters or
  44.  * arguments, when it is NULL the next  argv must be used . 
  45.  * p is always left pointing to the previous option or NULL.
  46.  * Consider the three equivalent valid argv's:
  47.  *        1        2         3
  48.  *        -a     -b       eric
  49.  *            -ab    eric
  50.  *        -aberic
  51.  * 
  52.  */
  53.  
  54. int
  55. getopt(argc, argv, optstr)
  56. int argc;
  57. char *argv[];
  58. char *optstr;        /* The list of valid options            */
  59. {
  60.     extern void err();    /* Forward reference            */
  61.  
  62.     static char *p = (char *)NULL;
  63.  
  64.     /*
  65.      * parsed all the options in this argv[]?
  66.      */
  67.     if (p == NULL || *++p == '\0' )
  68.     {
  69.         if (optind == argc)
  70.             return(EOF);
  71.         p = argv[optind];
  72.  
  73.         /*  a '-' by itself is not an option (e.g. see paste(1)) */
  74.         if (*p++ != '-' || *p == '\0') 
  75.             return(EOF);
  76.  
  77.         /* '--' marks the end of the option list.  */
  78.         if (*p == '-')
  79.         {
  80.             optind++;
  81.             return(EOF);
  82.         }
  83.     }
  84.  
  85.     optind++;
  86.     /*
  87.      * Look for a valid option 
  88.      */
  89.     while (*p != *optstr)
  90.     {    
  91.         if (*optstr == '\0')
  92.         {
  93.             /* Reached end of optstr, option not there */
  94.             err(argv[0], BAD_OPT, *p);
  95.             return((int)'?');
  96.         }
  97.         if (*++optstr == ':')
  98.             optstr++;
  99.     }
  100.  
  101.     /* If it does not need an argument then we are done.  */
  102.     if (*(optstr + 1) != ':')
  103.         return((int)*optstr);
  104.     
  105.     /*
  106.      * If there are more characters in this argv then it must
  107.      * be the argument.
  108.      */
  109.     if (*++p != '\0')
  110.     {
  111.         optarg = p;
  112.         p = (char *)NULL;
  113.         return((int)*optstr);
  114.     }
  115.  
  116.     /* 
  117.      * It needs an argument, but no more argv's left
  118.      */
  119.     if (optind == argc)
  120.     {
  121.         err(argv[0], MIS_ARG, *optstr);
  122.         p = (char *)NULL;
  123.         return((int)'?');
  124.     }
  125.  
  126.     /*
  127.      * Must be in next argv.
  128.      */
  129.     optarg = argv[optind++];
  130.     p = (char *)NULL;
  131.     return((int)*optstr);
  132. }
  133.  
  134. static void
  135. err(a0, e, c)
  136. char *a0;        /* argv[0]. i.e. the program name        */
  137. int e;
  138. char c;
  139. {
  140. #ifdef NO_STDIO
  141.     static char *errors[] = {
  142.         ": Illegal option -- ",
  143.         ": option requires an argument -- "
  144.     };
  145.     static char eend[] = "c\n";
  146.     
  147.  
  148.     if (opterr)
  149.     {
  150.         (void)write(2, a0, strlen(a0));
  151.         (void)write(2, errors[e], strlen(errors[e]));
  152.         eend[0] = c;
  153.         (void)write(2, eend, strlen(eend));
  154.     }
  155. #else
  156.     static char *errors[] = {
  157.         "%s: Illegal option -- %c\n",
  158.         "%s: option requires an argument -- %c\n"
  159.     };
  160.  
  161.     if (opterr)
  162.         fprintf(stderr, errors[e], a0, c);
  163. #endif
  164. }
  165.